﻿using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using ZeroSum.DependencyInjection.Attributes;
using ZeroSum.DependencyInjection.Interfaces;
using ZeroSum.Extensions;

namespace ZeroSum.App.Extensions;

internal static class AppServiceCollectionExtensions
{
    /// <summary>
    ///     扫描所有程序集，执行服务注册
    /// </summary>
    /// <param name="services"></param>
    /// <param name="configuration"></param>
    /// <returns></returns>
    public static IServiceCollection AddApp(this IServiceCollection services, IConfiguration configuration)
    {
        // 扫描所有程序集进行注册
        services.AddStartups(configuration);

        return services;
    }

    private static void AddStartups(this IServiceCollection services, IConfiguration configuration)
    {
        var assemblies = InternalApp.Assemblies;
        var target = typeof(IAppStartup);
        var types = assemblies.SelectMany(x => x.GetTypes().Where(t => t.IsPublic));

        // 查找所有实现了IAppStartup接口的普通类
        var startups = types.Where(x => target.IsAssignableFrom(x) && x.IsClass && !x.IsAbstract && !x.IsGenericType)
            .OrderByDescending(GetOrder);

        // 顺序执行Configuration
        foreach (var type in startups)
        {
            var startup = Activator.CreateInstance(type) as IAppStartup;
            startup?.ConfigurationServices(services, configuration);
        }
    }

    /// <summary>
    ///     对注册项进行排序
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    private static int GetOrder(Type type)
    {
        return type.HasAttribute<StartupOrder>() ? type.GetAttribute<StartupOrder>()!.Order : 0;
    }
}